home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-I386 / FLOPPY.H < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-17  |  6.6 KB  |  300 lines

  1. /*
  2.  * Architecture specific parts of the Floppy driver
  3.  *
  4.  * This file is subject to the terms and conditions of the GNU General Public
  5.  * License.  See the file "COPYING" in the main directory of this archive
  6.  * for more details.
  7.  *
  8.  * Copyright (C) 1995
  9.  */
  10. #ifndef __ASM_I386_FLOPPY_H
  11. #define __ASM_I386_FLOPPY_H
  12.  
  13. #include <linux/vmalloc.h>
  14.  
  15.  
  16. /*
  17.  * The DMA channel used by the floppy controller cannot access data at
  18.  * addresses >= 16MB
  19.  *
  20.  * Went back to the 1MB limit, as some people had problems with the floppy
  21.  * driver otherwise. It doesn't matter much for performance anyway, as most
  22.  * floppy accesses go through the track buffer.
  23.  */
  24. #define _CROSS_64KB(a,s,vdma) \
  25. (!vdma && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
  26.  
  27. #define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1)
  28.  
  29.  
  30. #define SW fd_routine[use_virtual_dma&1]
  31. #define CSW fd_routine[can_use_virtual_dma & 1]
  32.  
  33.  
  34. #define fd_inb(port)            inb_p(port)
  35. #define fd_outb(port,value)        outb_p(port,value)
  36.  
  37. #define fd_request_dma()        CSW._request_dma(FLOPPY_DMA,"floppy")
  38. #define fd_free_dma()           CSW._free_dma(FLOPPY_DMA)
  39. #define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
  40. #define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
  41. #define fd_free_irq()        free_irq(FLOPPY_IRQ, NULL)
  42. #define fd_get_dma_residue()    SW._get_dma_residue(FLOPPY_DMA)
  43. #define fd_dma_mem_alloc(size)    SW._dma_mem_alloc(size)
  44. #define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io)
  45.  
  46. #define FLOPPY_CAN_FALLBACK_ON_NODMA
  47.  
  48. static int virtual_dma_count=0;
  49. static int virtual_dma_residue=0;
  50. static char *virtual_dma_addr=0;
  51. static int virtual_dma_mode=0;
  52. static int doing_pdma=0;
  53.  
  54. static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
  55. {
  56.     register unsigned char st;
  57.  
  58. #undef TRACE_FLPY_INT
  59. #define NO_FLOPPY_ASSEMBLER
  60.  
  61. #ifdef TRACE_FLPY_INT
  62.     static int calls=0;
  63.     static int bytes=0;
  64.     static int dma_wait=0;
  65. #endif
  66.     if(!doing_pdma) {
  67.         floppy_interrupt(irq, dev_id, regs);
  68.         return;
  69.     }
  70.  
  71. #ifdef TRACE_FLPY_INT
  72.     if(!calls)
  73.         bytes = virtual_dma_count;
  74. #endif
  75.  
  76. #ifndef NO_FLOPPY_ASSEMBLER
  77.     __asm__ (
  78.        "testl %1,%1
  79.     je 3f
  80. 1:    inb %w4,%b0
  81.     andb $160,%b0
  82.     cmpb $160,%b0
  83.     jne 2f
  84.     incw %w4
  85.     testl %3,%3
  86.     jne 4f
  87.     inb %w4,%b0
  88.     movb %0,(%2)
  89.     jmp 5f
  90. 4:         movb (%2),%0
  91.     outb %b0,%w4
  92. 5:    decw %w4
  93.     outb %0,$0x80
  94.     decl %1
  95.     incl %2
  96.     testl %1,%1
  97.     jne 1b
  98. 3:    inb %w4,%b0
  99. 2:    "
  100.        : "=a" ((char) st), 
  101.        "=c" ((long) virtual_dma_count), 
  102.        "=S" ((long) virtual_dma_addr)
  103.        : "b" ((long) virtual_dma_mode),
  104.        "d" ((short) virtual_dma_port+4), 
  105.        "1" ((long) virtual_dma_count),
  106.        "2" ((long) virtual_dma_addr));
  107. #else    
  108.     {
  109.         register int lcount;
  110.         register char *lptr;
  111.  
  112.         st = 1;
  113.         for(lcount=virtual_dma_count, lptr=virtual_dma_addr; 
  114.             lcount; lcount--, lptr++) {
  115.             st=inb(virtual_dma_port+4) & 0xa0 ;
  116.             if(st != 0xa0) 
  117.                 break;
  118.             if(virtual_dma_mode)
  119.                 outb_p(*lptr, virtual_dma_port+5);
  120.             else
  121.                 *lptr = inb_p(virtual_dma_port+5);
  122.         }
  123.         virtual_dma_count = lcount;
  124.         virtual_dma_addr = lptr;
  125.         st = inb(virtual_dma_port+4);
  126.     }
  127. #endif
  128.  
  129. #ifdef TRACE_FLPY_INT
  130.     calls++;
  131. #endif
  132.     if(st == 0x20)
  133.         return;
  134.     if(!(st & 0x20)) {
  135.         virtual_dma_residue += virtual_dma_count;
  136.         virtual_dma_count=0;
  137. #ifdef TRACE_FLPY_INT
  138.         printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", 
  139.                virtual_dma_count, virtual_dma_residue, calls, bytes,
  140.                dma_wait);
  141.         calls = 0;
  142.         dma_wait=0;
  143. #endif
  144.         doing_pdma = 0;
  145.         floppy_interrupt(irq, dev_id, regs);
  146.         return;
  147.     }
  148. #ifdef TRACE_FLPY_INT
  149.     if(!virtual_dma_count)
  150.         dma_wait++;
  151. #endif
  152. }
  153.  
  154. static void fd_disable_dma(void)
  155. {
  156.     if(! (can_use_virtual_dma & 1))
  157.         disable_dma(FLOPPY_DMA);
  158.     doing_pdma = 0;
  159.     virtual_dma_residue += virtual_dma_count;
  160.     virtual_dma_count=0;
  161. }
  162.  
  163. static int vdma_request_dma(unsigned int dmanr, const char * device_id)
  164. {
  165.     return 0;
  166. }
  167.  
  168. static void vdma_nop(unsigned int dummy)
  169. {
  170. }
  171.  
  172.  
  173. static int vdma_get_dma_residue(unsigned int dummy)
  174. {
  175.     return virtual_dma_count + virtual_dma_residue;
  176. }
  177.  
  178.  
  179. static int fd_request_irq(void)
  180. {
  181.     if(can_use_virtual_dma)
  182.         return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
  183.                            "floppy", NULL);
  184.     else
  185.         return request_irq(FLOPPY_IRQ, floppy_interrupt,
  186.                            SA_INTERRUPT|SA_SAMPLE_RANDOM,
  187.                            "floppy", NULL);    
  188.  
  189. }
  190.  
  191. static unsigned long dma_mem_alloc(unsigned long size)
  192. {
  193.     return __get_dma_pages(GFP_KERNEL,__get_order(size));
  194. }
  195.  
  196.  
  197. static unsigned long vdma_mem_alloc(unsigned long size)
  198. {
  199.     return (unsigned long) vmalloc(size);
  200.  
  201. }
  202.  
  203. #define nodma_mem_alloc(size) vdma_mem_alloc(size)
  204.  
  205. static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
  206. {
  207.     if((unsigned int) addr >= (unsigned int) high_memory)
  208.         return vfree((void *)addr);
  209.     else
  210.         free_pages(addr, __get_order(size));        
  211. }
  212.  
  213. #define fd_dma_mem_free(addr, size)  _fd_dma_mem_free(addr, size) 
  214.  
  215. static void _fd_chose_dma_mode(char *addr, unsigned long size)
  216. {
  217.     if(can_use_virtual_dma == 2) {
  218.         if((unsigned int) addr >= (unsigned int) high_memory ||
  219.            virt_to_bus(addr) >= 0x1000000 ||
  220.            _CROSS_64KB(addr, size, 0))
  221.             use_virtual_dma = 1;
  222.         else
  223.             use_virtual_dma = 0;
  224.     } else {
  225.         use_virtual_dma = can_use_virtual_dma & 1;
  226.     }
  227. }
  228.  
  229. #define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size)
  230.  
  231.  
  232. static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
  233. {
  234.     doing_pdma = 1;
  235.     virtual_dma_port = io;
  236.     virtual_dma_mode = (mode  == DMA_MODE_WRITE);
  237.     virtual_dma_addr = addr;
  238.     virtual_dma_count = size;
  239.     virtual_dma_residue = 0;
  240.     return 0;
  241. }
  242.  
  243. static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
  244. {
  245. #ifdef FLOPPY_SANITY_CHECK
  246.     if (CROSS_64KB(addr, size)) {
  247.         printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size);
  248.         return -1;
  249.     }
  250. #endif
  251.     /* actual, physical DMA */
  252.     doing_pdma = 0;
  253.     clear_dma_ff(FLOPPY_DMA);
  254.     set_dma_mode(FLOPPY_DMA,mode);
  255.     set_dma_addr(FLOPPY_DMA,virt_to_bus(addr));
  256.     set_dma_count(FLOPPY_DMA,size);
  257.     enable_dma(FLOPPY_DMA);
  258.     return 0;
  259. }
  260.  
  261. struct fd_routine_l {
  262.     int (*_request_dma)(unsigned int dmanr, const char * device_id);
  263.     void (*_free_dma)(unsigned int dmanr);
  264.     int (*_get_dma_residue)(unsigned int dummy);
  265.     unsigned long (*_dma_mem_alloc) (unsigned long size);
  266.     int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
  267. } fd_routine[] = {
  268.     {
  269.         request_dma,
  270.         free_dma,
  271.         get_dma_residue,
  272.         dma_mem_alloc,
  273.         hard_dma_setup
  274.     },
  275.     {
  276.         vdma_request_dma,
  277.         vdma_nop,
  278.         vdma_get_dma_residue,
  279.         vdma_mem_alloc,
  280.         vdma_dma_setup
  281.     }
  282. };
  283.  
  284.  
  285. static int FDC1 = 0x3f0;
  286. static int FDC2 = -1;
  287.  
  288. #define FLOPPY0_TYPE    ((CMOS_READ(0x10) >> 4) & 15)
  289. #define FLOPPY1_TYPE    (CMOS_READ(0x10) & 15)
  290.  
  291. #define N_FDC 2
  292. #define N_DRIVE 8
  293.  
  294. #define FLOPPY_MOTOR_MASK 0xf0
  295.  
  296. #define AUTO_DMA
  297.  
  298.  
  299. #endif /* __ASM_I386_FLOPPY_H */
  300.